<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>react practice</title>
    <style>
        .warning {
            color: red;
            font-size: 28px
        }
    </style>
</head>
<body>
<div id="app"></div>
<script src="bower_components/react/react.js"></script>
<script src="bower_components/react/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script type="text/babel">
class TodoApp extends React.Component {
    constructor (props) {
        super(props)
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.state = {items: [], text: ''}
    }
    render() {
        return (
            <div>
                <h3>TODO</h3>
                <TodoList items={this.state.items}/>
                <form onSubmit={this.handleSubmit}>
                    <input onChange={this.handleChange} value={this.state.text}/>
                    <button>{'Add #' + (this.state.items.length + 1)}</button>
                </form>
            </div>
        )
    }
    handleChange(e) {
        this.setState({text: e.target.value})
    }
    handleSubmit (e) {
        e.preventDefault()
        var newItem = {
            text: this.state.text,
            id: Date.now()
        }
        this.setState((prevState) => ({
            items: prevState.items.concat(newItem),
            text: ''
        }))
    }
}
class TodoList extends React.Component{
    render(){
       return (
           <div>
           <ul>
           {this.props.items.map(item => (
               <li key={item.id}>{item.text}</li>
           ))}
           </ul>
           </div>
       )
    }
}
//    ReactDOM.render(<TodoApp />, document.getElementById('app'))

class Clock extends React.Component{
        constructor (props) {
            super(props)
            this.state = {date: new Date()}
        }
        componentDidMount () { // 当组件输出到 DOM 后会执行
            this.timerID = setInterval(
                () => this.tick(),
                1000
            )
        }
        componentWillUnmount() {
            clearInterval(this.timerID)
        }
        tick() {
            this.setState({
                date: new Date()
            })
        }
        render () {
            return (
                <div>
                    <h1>Hello world</h1>
                    <h2>It is {this.state.date.toLocaleTimeString()}</h2>
                </div>
            )
        }
}
class Toggle extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            isToggleOn: true
        }
        this.handleClick = this.handleClick.bind(this)
    }
    handleClick () {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
        }))
    }
    render () {
        return (
                <button onClick={this.handleClick}>
                    {this.state.isToggleOn ? 'ON' : 'OFF'}
                </button>
        )
    }
}
class UserGreeting extends React.Component{
    render () {
        return (
            <h1>welcome back</h1>
        )
    }
}
class GuestGreeting extends React.Component{
    render () {
        return (
                <h1>please sign up</h1>
        )
    }
}
class Greeting extends React.Component{
    constructor(props) {
        super(props)
        this.greeting = this.greeting.bind(this)
    }
    greeting () {
        if (this.props.isLoggedIn) {
            return <UserGreeting/>
        }
        return  <GuestGreeting/>
    }
    render () {
        return (
            <div>
                {this.greeting()}
            </div>
        )
    }
}
// 登录
function LoginButton(props) {
    return (
            <button onClick={props.onClick}>
                Login
            </button>
    )
}

function LogoutButton(props) {
    return (
            <button onClick={props.onClick}>
                Logout
            </button>
    )
}
class LoginControl extends React.Component{
    constructor(props){
        super(props)
        this.state ={ isLoggedIn: false}
        this.handleLogoutClick = this.handleLogoutClick.bind(this)
        this.handleLoginClick = this.handleLoginClick.bind(this)
    }
    handleLogoutClick () {
      this.setState({isLoggedIn: false})
    }
    handleLoginClick () {
        this.setState({isLoggedIn: true})
    }
    render () {
        const isLoggedIn = this.state.isLoggedIn
        let button = null
        if (isLoggedIn) {
            button = <LogoutButton onClick={this.handleLogoutClick} />
        } else {
            button = <LoginButton onClick={this.handleLoginClick} />
        }
        return (
            <div>
                <Greeting isLoggedIn={isLoggedIn}/>
                {button}
            </div>
        )
    }
}
// 阻止组件渲染
function WarningBanner(props) {
    if (props.warn) {
        return null
    }
    return (
        <div className="warning">
            Warning!
        </div>
    )
}
function NumberList(props) {
    const numbers = props.numbers
    // const listItems = numbers.map((number, index) =>
    //        <li key={index}>{number}</li>
    // )
    // return (
    //     <ul>
    //        {listItems}
    //    </ul>
    //)
    return (
            <ul>
                {numbers.map((number, index) =>
                        <li key={index}>{number}</li>
                )}
            </ul>
    )
}
class Page extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            showWarning: true,
            numbers: [1, 2, 3, 4, 5, 6]
        }
        this.handleToggleClick = this.handleToggleClick.bind(this)
    }
    handleToggleClick () {
        this.setState(prevState => ({
            showWarning: !prevState.showWarning
        }))
    }
    render () {
        return (
            <div>
                <NumberList numbers={this.state.numbers}/>
                <WarningBanner warn={this.state.showWarning}/>
                <button onClick={this.handleToggleClick}>
                    {this.state.showWarning ? 'Hide' : 'Show'}
                </button>
            </div>
        )
    }
}
// input
class NameForm extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            value: ''
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }
    handleChange(e){
        this.setState({
            value: e.target.value.toUpperCase()
        })
    }
    handleSubmit (e) {
        alert('A NAME WAS SUBMITTED: ' + this.state.value)
        e.preventDefault()
    }
    render () {
        return (
                <form onSubmit={this.handleSubmit}>
                    <label>Name：
                        <input type="text" value={this.state.value} onChange={this.handleChange}/>
                        <input type="submit" value="Submit"/>
                    </label>
                </form>
        )
    }
}
// select
class FlavorForm extends React.Component{
    constructor (props) {
        super(props)
        this.state = {
            value: 'coconut'
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }
    handleChange (e) {
        this.setState({
            value: e.target.value
        })
    }
    handleSubmit (e) {
        alert('your favorite falvor is: ' + this.state.value)
        e.preventDefault()
    }
    render () {
        return (
                <form onSubmit={this.handleSubmit}>
                    <label>pick your favorite la croix flavor:</label>
                    <select value={this.state.value} onChange={this.handleChange}>
                        <option value="grapefruit">grapefruit</option>
                        <option value="lime">lime</option>
                        <option value="coconut">coconut</option>
                        <option value="mango">mango</option>
                    </select>
                    <input type="submit" value="submit"/>
                </form>
        )
    }
}
// 多个输入的解决方法
class Reservation extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            isGoing: true,
            numberOfGuests: 2
        }
        this.handleInputChange = this.handleInputChange.bind(this)
    }
    handleInputChange (e) {
        const target = e.target
        const value = target.type === 'checkbox' ? target.checked : target.value
        const name = target.name
        this.setState({
            [name]: value
        })
    }
    render () {
        return (
                <form>
                    <label>
                        Is going:
                        <input
                                name="isGoing"
                                type="checkbox"
                                checked={this.state.isGoing}
                                onChange={this.handleInputChange}
                        />
                    </label>
                    <br/>
                    <label>
                        Number of guests:
                        <input
                                name="numberOfGuests"
                                type="number"
                                checked={this.state.numberOfGuests}
                                onChange={this.handleInputChange}
                        />
                    </label>
                </form>
        )
    }
}
// 状态提升
function BoilingVerdict(props) {
    if(props.celsius >= 100) {
        return <p>水会烧开</p>
    }
    return <p>水不会烧开</p>
}
class Calculator extends React.Component{
    constructor(props){
        super(props)
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this)
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this)
        this.state = {temperature: '', scale: 'c'}
    }
    handleCelsiusChange (temperature) {
      this.setState({scale: 'c', temperature})
    }
    handleFahrenheitChange(temperature) {
        this.setState({scale: 'f', temperature})
    }
    render () {
        const scale = this.state.scale
        const temperature = this.state.temperature
        const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature
        const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature
        return (
            <div>
                <TemperatureInput scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange}/>
                <TemperatureInput scale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange}/>
                <BoilingVerdict celsius={parseFloat(celsius)}/>
            </div>
        )
    }
}
// 华氏度，摄氏度
function toCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9;
}

function toFahrenheit(celsius) {
    return (celsius * 9 / 5) + 32;
}
function tryConvert(temperature, convert) {
    const input = parseFloat(temperature);
    if (Number.isNaN(input)) {
        return '';
    }
    const output = convert(input);
    const rounded = Math.round(output * 1000) / 1000;
    return rounded.toString();
}
const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
}
class TemperatureInput extends React.Component{
    constructor(props){
        super(props)
        this.handleChange = this.handleChange.bind(this)
    }
    handleChange(e){
        this.props.onTemperatureChange(e.target.value)
    }
    render(){
        const temperature = this.props.temperature
        const scale = this.props.scale
        return (
            <fieldset>
                <legend>Enter temperature in {scaleNames[scale]}:</legend>
                <input value={temperature} onChange={this.handleChange}/>
            </fieldset>
        )
    }
}
// refs
class CustomTextInput extends React.Component{
    constructor(props){
        super(props)
        this.focus = this.focus.bind(this)
    }
    focus(){
        this.textInput.focus()
    }
    render(){
        return(
            <div>
                <input type="text"
                ref={input => this.textInput = input}/>
                <input type="button" value="Focus the text input" onClick={this.focus}/>
            </div>
        )
    }
}
class AutoFocusTextInput extends React.Component{
    componentDidMount(){
        this.textInput.focus()
    }
    render(){
        return(
            <CustomTextInput ref={input => this.textInput = input}/>
        )
    }
}
class RootApp extends React.Component{
    render () {
        return (
                <div>
                    <TodoApp/>
                    <Clock/>
                    <Toggle/>
                    <Greeting isLoggedIn={true}/>
                    <LoginControl/>
                    <Page/>
                    <NameForm/>
                    <FlavorForm/>
                    <Reservation/>
                    <Calculator/>
                    <AutoFocusTextInput/>
                </div>
        )
    }
}
ReactDOM.render(<RootApp />, document.getElementById('app'))
</script>
</body>
</html>